In [2]:
import pandas as pd
from mplsoccer.pitch import Pitch
import matplotlib.pyplot as plt
import panel as pn
pn.extension()
import param
import ast
import numpy as np
from matplotlib import rcParams
rcParams['text.color'] = '#c7d5cc'
rcParams["figure.facecolor"] = "#22312b"

pd.options.display.max_columns = None
%matplotlib inline

import warnings
warnings.filterwarnings('ignore')
In [3]:
df_events = pd.read_csv('invincible_dashboard.csv')

#df_events = df_events.sort_values(by = 'match_week')

df_events.loc[df_events['type_name'].isin(['Duel', 'Foul Committed']), 'type_name'] = 'Foul & Tackles'
In [4]:
list_metric_gridmap = ['Foul & Tackles', 'Pressure']
list_player_names = df_events['player_name'].unique()
In [5]:
class DF_Dashboard(param.Parameterized):
    
    
    metric_for_Gridmap = param.ObjectSelector(default='Foul & Tackles', objects = list_metric_gridmap)
    Player = param.ObjectSelector(default='Thierry Henry', objects = list_player_names) 
    
    
    def shots_map(self):
        player_name = self.Player
        metric = self.metric_for_Gridmap
        mask1 = df_events['type_name'] == 'Shot'
        mask2 = df_events['player_name'] == player_name
        
        df_shots = df_events[mask1 & mask2]
        df_non_goal = df_shots[df_shots['shot_outcome_name'] != 'Goal']
        df_goal = df_shots[df_shots['shot_outcome_name'] == 'Goal']
        
        plt.style.use('ggplot')
        pitch = Pitch(pitch_type='statsbomb', orientation='vertical',view='half',
                      pitch_color='#22312b', line_color='#c7d5cc',
                      constrained_layout=False, tight_layout=True)
        fig, ax = pitch.draw()
        
        ax.set_title('Shot Map: {} goals, {} xG'.format(len(df_goal),df_shots["shot_statsbomb_xg"].sum().round(1)), fontsize=18, pad=12,color="#22312b")
        pitch.scatter(df_non_goal["location_x"], df_non_goal["location_y"], c='#5499C7', alpha = 0.75,
                           s=[xg*200 for xg in df_non_goal["shot_statsbomb_xg"]], ax=ax,label='Other')
        pitch.scatter(df_goal["location_x"], df_goal["location_y"], c='yellow', edgecolors='black', alpha = 0.75,
                           s=[xg*200 for xg in df_goal["shot_statsbomb_xg"]], ax=ax,label='Goal')
        ax.legend(facecolor='#22312b', edgecolor='None', fontsize=12, loc='lower left')
        plt.close()
        
        return ax.figure
        
        
    def keypass_map(self):
        player_name = self.Player
        metric = self.metric_for_Gridmap
        mask1 = df_events['type_name'] == 'Pass'
        mask2 = df_events['player_name'] == player_name

        df_pass = df_events[mask1 & mask2]
        df_non_assist = df_pass[df_pass['pass_goal_assist'] != True]
        df_assist = df_pass[df_pass['pass_goal_assist'] == True]


        plt.style.use('ggplot')
        pitch = Pitch(pitch_type='statsbomb', orientation='horizontal',
                      pitch_color='#22312b', line_color='#c7d5cc',
                      constrained_layout=False, tight_layout=True)
        fig, ax = pitch.draw()

        ax.set_title('KeyPass Map: {} assisted shot, {} assist'.format(len(df_pass),(df_pass['pass_goal_assist']==True).sum()), fontsize=18, pad=12,color="#22312b")
        pitch.arrows(df_non_assist["location_x"], df_non_assist["location_y"],
                     df_non_assist["pass_end_location_x"], df_non_assist["pass_end_location_y"], width=1.3,
                     headwidth=6, headlength=6, color='#5499C7', ax=ax, label='assisted shot')
        pitch.arrows(df_assist["location_x"], df_assist["location_y"],
                     df_assist["pass_end_location_x"], df_assist["pass_end_location_y"], width=1.5,
                     headwidth=6, headlength=6, color='yellow', ax=ax, label='assist')
        ax.legend(facecolor='#22312b', handlelength=2, edgecolor='None', fontsize=12, loc='lower left')
        plt.close()

        return ax.figure
        
    
    def grid_map(self):   
        player_name = self.Player
        metric = self.metric_for_Gridmap
        
        mask1 = df_events['type_name'] == metric
        mask2 = df_events['player_name'] == player_name

        df_metric = df_events[mask1 & mask2]
        
        grid = (6,5)
        
        pitch = Pitch(pitch_type='statsbomb',
                      pitch_color='#22312b', line_color='#c7d5cc', orientation='vertical', line_zorder=2,
                     constrained_layout=False, tight_layout=True, figsize = (6,8.1))
        fig, ax = pitch.draw()
        
        bin_statistic = pitch.bin_statistic(df_metric['location_x'], df_metric['location_y'], statistic='count', bins=grid)
        
        pitch.heatmap(bin_statistic, ax=ax, cmap='coolwarm', edgecolors='#22312b')
        pitch.scatter(df_metric['location_x'], df_metric['location_y'], c='white', s=2, ax=ax)
        bin_statistic['statistic'] = (pd.DataFrame((bin_statistic['statistic'] / bin_statistic['statistic'].sum())).applymap(lambda x: '{:.0%}'.format(x)).values)
        pitch.label_heatmap(bin_statistic, color='white', fontsize=16, weight = 'bold', ax=ax, ha='center', va='bottom')
        ax.set_title('{} {} Locations'.format(len(df_metric), metric), fontsize=18, pad=12,color="#22312b")
        ax.annotate("", xy = (2,20), xytext=(2, 2), arrowprops=dict(arrowstyle="->", linewidth=3.5))
        ax.text(3,4,'Attack',fontsize=12, color = 'white', fontweight = 'bold')
        plt.close()
        
        return ax.figure
In [6]:
DBshow = DF_Dashboard(name='')

# create a title for the dashboard
dashboard_title = '## Invincibles Player Actions 2003/04'
dashboard_subtitle = 'This dashboard shows a Shot map, a Key Passes map and a Pitch GridMap based on the metric and a player you select from the right'
footer = 'Note : The data is based on 32/38 games from the Arsenals Invincible season'

# create a dashboard, defining the layout as one column containing the
# dashboard title, dashboard description, 'Animal' drop down selector,
# box plot, and data table
dashboard = pn.Column(
    pn.Row(
        pn.Column(dashboard_title, dashboard_subtitle, align = 'start'),
        pn.Spacer(width = 150),
        pn.Column(DBshow.param)),
    pn.Row(pn.Column(pn.Row(DBshow.keypass_map), pn.Row(DBshow.shots_map), background='#22312b'), 
           pn.Column(DBshow.grid_map, background='#22312b')),
    pn.Row(pn.Column(footer,align='center',sizing_mode='stretch_width'),pn.Spacer(width=100),pn.Spacer(width=130),pn.pane.JPG("statsbomb-logo.jpg",align='center',width=200,height_policy='fit'),height_policy='min')
)


dashboard.embed()
#dashboard
                                                                                                                       
Attribution: Created by Ashay Shah. Inspired by twitter.com/52_break. Code toggle possible thanks to github.com/csaid.
In [ ]: